package com.megagoodsoftware.smugmug;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;

//import com.megagoodsoftware.MediaShare.Flickr;
//import com.megagoodsoftware.SmugMug.PhotoSize;


/**
 * A photo is represented by a title, the date at which it was taken and a URL.
 * The URL depends on the desired {@link com.megagoodsoftware.smugmug.google.android.photostream.Flickr.PhotoSize}.
 */
public class Photo implements Parcelable {
    private String mId;
    private String mSecret;
    private String mServer;
    private String mFarm;
    private String mTitle;
    private String mDate;
    private String mSmallUrl;
	private String mMediumUrl;
    
    static final String PHOTO_IMAGE_URL = "http://farm%s.static.flickr.com/%s/%s_%s%s.jpg";
    static final int IO_BUFFER_SIZE = 4 * 1024;
    static final boolean FLAG_DECODE_PHOTO_STREAM_WITH_SKIA = false;

    public Photo() {
    }

    private Photo(Parcel in) {
        setId(in.readString());
        setSecret(in.readString());
        setServer(in.readString());
        setFarm(in.readString());
        setTitle(in.readString());
        setDate(in.readString());
        setSmallUrl(in.readString());
        setMediumUrl(in.readString());

    }

    /**
     * Returns the title of the photo, if specified.
     *
     * @return The title of the photo. The returned value can be empty or null.
     */
    public String getTitle() {
        return mTitle;
    }

    /**
     * Returns the date at which the photo was taken, formatted in the current locale
     * with the following pattern: MMMM d, yyyy.
     *
     * @return The title of the photo. The returned value can be empty or null.
     */
    public String getDate() {
        return mDate;
    }

    /**
     * Copy the content of the input stream into the output stream, using a temporary
     * byte array buffer whose size is defined by {@link #IO_BUFFER_SIZE}.
     *
     * @param in The input stream to copy from.
     * @param out The output stream to copy to.
     *
     * @throws IOException If any error occurs during the copy.
     */
    static void copy(InputStream in, OutputStream out) throws IOException {
        byte[] b = new byte[IO_BUFFER_SIZE];
        int read;
        while ((read = in.read(b)) != -1) {
            out.write(b, 0, read);
        }
    }

    /**
     * Returns the URL to the photo for the specified size.
     *
     * @param photoSize The required size of the photo.
     *
     * @return A URL to the photo for the specified size.
     *
     * @see com.megagoodsoftware.smugmug.google.android.photostream.Flickr.PhotoSize
     */
    public String getUrl(PhotoSize photoSize) {
        return String.format(PHOTO_IMAGE_URL, getFarm(), getServer(), getId(), getSecret(), photoSize.size());
    }

    /**
     * Closes the specified stream.
     *
     * @param stream The stream to close.
     */
    static void closeStream(Closeable stream) {
        if (stream != null) {
            try {
                stream.close();
            } catch (IOException e) {
                android.util.Log.e(Constants.TAG, "Could not close stream", e);
            }
        }
    }


    /**
     * Loads a Bitmap representing the photo for the specified size. The Bitmap is loaded
     * from the URL returned by
     * {@link #getUrl(com.megagoodsoftware.smugmug.google.android.photostream.Flickr.PhotoSize)}. 
     *
     * @param size The size of the photo to load.
     *
     * @return A Bitmap whose longest size is the same as the longest side of the
     *         specified {@link com.megagoodsoftware.smugmug.google.android.photostream.Flickr.PhotoSize}, or null
     *         if the photo could not be loaded.
     */
    public Bitmap loadPhotoBitmap(PhotoSize size) {
        Bitmap bitmap = null;
        InputStream in = null;
        BufferedOutputStream out = null;
        String urlToUse;
        
        if (size.equals(PhotoSize.MEDIUM)) {
        	urlToUse = mMediumUrl;
        } else {
        	urlToUse = mSmallUrl;
        }
        
        try {
            in = new BufferedInputStream(new URL(urlToUse).openStream(),
                    IO_BUFFER_SIZE);

            if (FLAG_DECODE_PHOTO_STREAM_WITH_SKIA) {
                bitmap = BitmapFactory.decodeStream(in);
            } else {
                final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
                out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
                copy(in, out);
                out.flush();

                final byte[] data = dataStream.toByteArray();
                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            }
        } catch (IOException e) {
            android.util.Log.e(Constants.TAG, "Could not load photo: " + this, e);
        } finally {
            closeStream(in);
            closeStream(out);
        }

        return bitmap;
    }

    @Override
    public String toString() {
        return getTitle() + ", " + getDate() + " @" + getId();
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(getId());
        dest.writeString(getSecret());
        dest.writeString(getServer());
        dest.writeString(getFarm());
        dest.writeString(getTitle());
        dest.writeString(getDate());
        dest.writeString(getSmallUrl());
        dest.writeString(getMediumUrl());
    }

    public void setId(String mId) {
		this.mId = mId;
	}

	public String getId() {
		return mId;
	}

	public void setSecret(String mSecret) {
		this.mSecret = mSecret;
	}

	public String getSecret() {
		return mSecret;
	}

	public void setServer(String mServer) {
		this.mServer = mServer;
	}

	public String getServer() {
		return mServer;
	}

	public void setFarm(String mFarm) {
		this.mFarm = mFarm;
	}

	public String getFarm() {
		return mFarm;
	}

	public void setTitle(String mTitle) {
		this.mTitle = mTitle;
	}

	public void setDate(String mDate) {
		this.mDate = mDate;
	}

	public static final Parcelable.Creator<Photo> CREATOR = new Parcelable.Creator<Photo>() {
        public Photo createFromParcel(Parcel in) {
            return new Photo(in);
        }

        public Photo[] newArray(int size) {
            return new Photo[size];
        }
    };

	public void setSmallUrl(String url) {
		this.mSmallUrl = url;
		
	}

	public void setMediumUrl(String url) {
		this.mMediumUrl = url;
		
	}
	public String getSmallUrl() {
		return mSmallUrl;
		
	}

	public String getMediumUrl() {
		return mMediumUrl;
		
	}
}